/*
* $Id: ListenerBasedNodeUpdater.java,v 1.2 2006/09/25 08:52:36 acaproni Exp $
*
* $Date: 2006/09/25 08:52:36 $
* $Revision: 1.2 $
* $Author: acaproni $
*
* Copyright CERN, All Rights Reserved.
*/
package cern.gp.beans.impl;
/**
* <i><font size="-1" color="#FF0000">**Experimental : for internal use only** </font></i>
* Provides support for implementing a <code>NodeUpdater</code>.
* <p>
* A bean that implements the <code>NodeUpdaterProvider</code> interface, in
* order to dynamically update the GUI, will typically use this class as the
* <code>NodeUpdater</code> that is returned.
* </p>
* <p>
* The setter methods should be used to set the initial values and to notify of a new
* value.
* </p>
*
* @version $Revision: 1.2 $ $Date: 2006/09/25 08:52:36 $
* @author Lionel Mestre
*
*/
abstract class ListenerBasedNodeUpdater implements NodeUpdater {
private ListenerList eventListeners;
//
// -- CONSTRUCTORS -----------------------------------------------
//
/**
* Creates a new <code>ListenerBasedNodeUpdater</code>
*/
protected ListenerBasedNodeUpdater() {
eventListeners = new WeakReferenceListenerList();
}
//
// -- PUBLIC METHODS -----------------------------------------------
//
//
// -- implements NodeUpdater -----------------------------------------------
//
public void addNodeUpdaterListener(NodeUpdaterListener listener) {
synchronized (eventListeners) {
if (!eventListeners.contains(listener)) {
eventListeners.add(listener);
}
}
}
public void removeNodeUpdaterListener(NodeUpdaterListener listener) {
synchronized (eventListeners) {
eventListeners.remove(listener);
}
}
//
// -- PROTECTED METHODS -----------------------------------------------
//
/**
* Returns true is this support has at least one registered listener
* @return true is this support has at least one registered listener
*/
protected final boolean hasListeners() {
return !eventListeners.isEmpty();
}
protected final void fireNameChange(String newName) {
if (! hasListeners()) return;
synchronized (eventListeners) {
java.util.Iterator iterator = eventListeners.iterator();
while (iterator.hasNext()) {
((NodeUpdaterListener) iterator.next()).nameChanged(newName);
}
}
}
protected final void fireDisplayNameChange(String newDisplayName) {
if (! hasListeners()) return;
synchronized (eventListeners) {
java.util.Iterator iterator = eventListeners.iterator();
while (iterator.hasNext()) {
((NodeUpdaterListener) iterator.next()).displayNameChanged(newDisplayName);
}
}
}
protected final void fireShortDescriptionChange(String newShortDescription) {
if (! hasListeners()) return;
synchronized (eventListeners) {
java.util.Iterator iterator = eventListeners.iterator();
while (iterator.hasNext()) {
((NodeUpdaterListener) iterator.next()).shortDescriptionChanged(newShortDescription);
}
}
}
protected final void fireNodeDefaultActionChange(String newDefaultAction) {
if (! hasListeners()) return;
synchronized (eventListeners) {
java.util.Iterator iterator = eventListeners.iterator();
while (iterator.hasNext()) {
((NodeUpdaterListener) iterator.next()).nodeDefaultActionChanged(newDefaultAction);
}
}
}
protected final void fireNodeIconChange(java.awt.Image newIcon) {
if (! hasListeners()) return;
synchronized (eventListeners) {
java.util.Iterator iterator = eventListeners.iterator();
while (iterator.hasNext()) {
((NodeUpdaterListener) iterator.next()).nodeIconChanged(newIcon);
}
}
}
//
// -- PRIVATE METHODS -----------------------------------------------
//
//
// -- INNER CLASSES -----------------------------------------------
//
/**
* A class implementing this interface provide a minimum set of methods
* to support the addition and removal of listener.
* @author Lionel Mestre
*/
private interface ListenerList {
/**
* Returns true if no listener is in the list.
* @return true if no listener is in the list.
*/
public boolean isEmpty();
/**
* Returns the number of listeners in the list.
* @return the number of listeners in the list.
*/
public int size();
/**
* Returns true if <code>listener</code> is a listener contained in the list.
* @return true if <code>listener</code> is a listener contained in the list.
*/
public boolean contains(NodeUpdaterListener listener);
/**
* Adds the given listener
* @param <code>listener</code> the listener to add in the list
* @return true if the listener has been added.
*/
public boolean add(NodeUpdaterListener listener);
/**
* Removes the given listener
* @param <code>listener</code> the listener to remove from the list
* @return true if the listener has been removed.
*/
public boolean remove(NodeUpdaterListener listener);
/**
* Returns an iterator on the listeners of the list
* @return an iterator on the listeners of the list
*/
public java.util.Iterator iterator();
}
/**
* Implements a simple list of listeners backed by an <code>ArrayList</code>.
* @author Lionel Mestre
*/
private class PlainListenerList implements ListenerList {
protected java.util.ArrayList list;
public PlainListenerList() {
list = new java.util.ArrayList();
}
public boolean isEmpty() {
return list.isEmpty();
}
public int size() {
return list.size();
}
public boolean contains(NodeUpdaterListener listener) {
return list.contains(listener);
}
public boolean add(NodeUpdaterListener listener) {
return list.add(listener);
}
public boolean remove(NodeUpdaterListener listener) {
return list.remove(listener);
}
public java.util.Iterator iterator() {
return list.iterator();
}
}
/**
* Implements a list of listeners in which the reference to one listener
* is a WeakReference allowing that listener to be garbage collected if
* it is no more used.
* @author Lionel Mestre
*/
private class WeakReferenceListenerList extends PlainListenerList {
public WeakReferenceListenerList() {
}
public boolean contains(NodeUpdaterListener listener) {
java.util.Iterator iterator = iterator();
while (iterator.hasNext()) {
if (iterator.next() == listener)
return true;
}
return false;
}
public boolean add(NodeUpdaterListener listener) {
return list.add(new java.lang.ref.WeakReference(listener));
}
public boolean remove(NodeUpdaterListener listener) {
java.util.Iterator iterator = iterator();
while (iterator.hasNext()) {
if (iterator.next() == listener) {
iterator.remove();
return true;
}
}
return false;
}
public java.util.Iterator iterator() {
return new WeakReferenceIterator(list.iterator());
}
}
/**
* Implements an <code>Iterator</code> on a list containing
* <code>WeakReference</code>s and return the referenced object.
* The iterator automatically removed from the list the objects
* that have been garbage collected.
*
* @author Lionel Mestre
*
*/
private class WeakReferenceIterator implements java.util.Iterator {
private java.util.Iterator iterator;
private Object nextObject;
public WeakReferenceIterator(java.util.Iterator iterator) {
this.iterator = iterator;
nextObject = getNextObject();
}
public boolean hasNext() {
return nextObject != null;
}
public Object next() {
Object result = nextObject;
nextObject = getNextObject();
return result;
}
public void remove() {
iterator.remove();
}
private Object getNextObject() {
while (iterator.hasNext()) {
java.lang.ref.WeakReference ref = (java.lang.ref.WeakReference) iterator.next();
Object target = ref.get();
if (target == null) {
// object has been removed
iterator.remove();
} else {
return target;
}
}
return null;
}
} // end inner class WeakReferenceIterator
}